#!/bin/env python

from xml.dom.minidom import parse
import os

class Module:
    def __init__(self, org, name, rev, dependencies):
        self.org = org
        self.name = name
        self.rev = rev
        self.dependencies = dependencies

    def __repr__(self):
        d = ""
        for dep in self.dependencies:
            d = d + repr(dep) + " "
        if len(d)>0:
            d = ' [' + d[:-1] + ']'
        return '%s-%s-%s%s' % (self.org, self.name, self.rev, d)

    def __eq__(self, other):
        return (self.org==other.org) and (self.name==other.name) and (self.rev==other.rev)

    def __hash__(self):
        return self.org.__hash__() ^ self.name.__hash__() ^ self.rev.__hash__()


class IvyParser:
    def __init__(self, repositoryRoot):
        self.repositoryRoot = repositoryRoot

    def domElement2module(self, d):
        org = d.attributes["org"].value
        name = d.attributes["name"].value
        rev = d.attributes["rev"].value
        dependencies = self.getDependencies(org, name, rev)
        return Module(org, name, rev, dependencies)

    def dom2modules(self, dom):
        modules = []
        for d in dom.getElementsByTagName('dependency'):
            modules.append(self.domElement2module(d))
        return modules

    def parseFile(self, file):
        dom = parse(file)
        return self.dom2modules(dom)

    def getDependencies(self, org, name, rev):
        path = self.repositoryRoot + '/' + org + '/' + name + '/' + rev + '/ivy.xml'
        if os.path.exists(path):
            return self.parseFile(path)
        else:
            return []

    def flatfy(self, modules):
        modulesSet = set()
        self.flatfyRecursive(modulesSet, modules)
        return modulesSet

    def flatfyRecursive(self, modulesSet, modules):
        for module in modules:
            m = Module(module.org, module.name, module.rev, [])
            modulesSet.add(m)
            self.flatfyRecursive(modulesSet, module.dependencies)

    def scanRepository(self):
        modules = set()
        for root, dirs, files in os.walk(top=self.repositoryRoot, topdown=True):
            for dir in dirs:
                fulldir = root.replace('\\','/') + "/" + dir
                fulldir = fulldir[len(self.repositoryRoot)+1:]
                tokens = fulldir.split('/')
                if ('.svn' not in fulldir) and (len(tokens)==3):
                    modules.add(Module(tokens[0], tokens[1], tokens[2], []))
        return modules

    def removeModulesFromRepository(self, modules):

        toRemove = []

        for module in modules:
            revpath = self.repositoryRoot +'/' + module.org + '/' + module.name + '/' + module.rev
            toRemove.append(revpath)

        for module in modules:
            namepath = self.repositoryRoot +'/' + module.org + '/' + module.name
            if (not namepath in toRemove) and self.isGoingToBeEmpty(namepath, toRemove):
                toRemove.append(namepath)

        for module in modules:
            orgpath = self.repositoryRoot +'/' + module.org
            if (not orgpath in toRemove) and self.isGoingToBeEmpty(orgpath, toRemove):
                toRemove.append(orgpath)

        for path in toRemove:
            os.popen('svn remove ' + path)

    def isGoingToBeEmpty(self, folder, toRemove):
        children = os.listdir(folder)
        for child in children:
            fullchildpath = folder + '/' + child
            if not ((child=='.svn') or (fullchildpath in toRemove)):
                return False
        return True

def main():
    p = IvyParser('ivy-repository')

    prj = p.parseFile('ivy.xml')
    tools = p.parseFile('conf/build/ivy-tools.xml')
    used = p.flatfy(prj + tools)

    available = p.scanRepository()

    unused = available - used
    for module in unused:
        print module

    p.removeModulesFromRepository(unused)

if __name__ == "__main__":
    main()






